package com.example.utils;


import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 文件和文件夹操作工具类。
 * 提供了一系列用于文件和文件夹操作的静态方法。
 */
public class FileUtils {
    /**
     * 使用FileWriter将消息写入指定的日志文件
     * 如果指定的文件或路径不存在，会自动创建
     * 写入的消息前面会加上当前的时间戳
     *
     * @param path        日志文件所在的路径
     * @param logFileName 日志文件的名称
     * @param message     要写入的消息内容
     */
    public static void fileByWriter(String path, String logFileName, String message) {
        try {
            // 创建文件路径对象
            File files = new File(path);
            // 创建文件对象，路径加文件名
            File file = new File(path + "\\" + logFileName);
            // 检查文件和路径是否存在，不存在则创建
            if (!file.exists() || !files.exists()) {
                files.mkdirs();
                file.createNewFile();
            }
            // 创建FileWriter对象，设置为追加写入模式
            FileWriter fw = new FileWriter(file, true);
            // 创建BufferedWriter对象，用于写入带缓冲的消息
            BufferedWriter bw = new BufferedWriter(fw);
            // 写入带有时间戳的消息，并换行
            bw.write("[" + GetFormat.getDate10() + "]  " + message + "\r\n\r\n");
            // 刷新缓冲区，确保数据写入文件
            bw.flush();
            // 关闭BufferedWriter
            bw.close();
        } catch (Exception e) {
            // 如果发生异常，递归调用此方法，将异常信息写入日志
            fileByWriter(path, logFileName, e.getMessage());
        }
    }

    /**
     * 创建指定路径的文件夹
     * 如果文件夹不存在，则创建文件夹；如果存在，则直接返回文件夹路径
     *
     * @param rootFile 文件夹的路径
     * @return 返回创建或已存在的文件夹路径
     */
    public static String writeFile(String rootFile) {
        // 根据路径创建一个File对象
        File file = new File(rootFile);
        // 检查文件夹是否不存在
        if (!file.exists()) {
            // 创建文件夹
            file.mkdirs();
            // 返回创建的文件夹路径
            return rootFile;
        }
        // 如果文件夹已存在，直接返回文件夹路径
        return rootFile;
    }

    /**
     * 拷贝文件
     *
     * @param oldPath 原文件路径
     * @param newPath 新文件路径
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            // 创建原文件对象
            File oldFile = new File(oldPath);
            // 创建新文件对象
            File file = new File(newPath);
            // 创建文件输入流
            FileInputStream in = new FileInputStream(oldFile);
            // 创建文件输出流
            FileOutputStream out = new FileOutputStream(file);
            // 定义字节数组作为缓冲区，大小为2MB
            byte[] buffer = new byte[2097152];
            int readByte = 0;
            // 循环读取原文件内容并写入新文件，直到读取完毕
            while ((readByte = in.read(buffer)) != -1) {
                out.write(buffer, 0, readByte);
            }
            // 关闭文件输入流
            in.close();
            // 关闭文件输出流
            out.close();
        } catch (Exception e) {
            // 记录错误日志
            e.printStackTrace();
        }
    }


    /**
     * 移动文件
     * 将指定路径下的文件移动到新路径
     * 如果新路径下已存在同名文件，则删除该文件
     * 如果新路径不存在，则创建该路径
     *
     * @param path       原文件路径
     * @param strNewPath 新路径
     */
    public static void movesFile(String path, String strNewPath) {
        // 创建原文件对象
        File fold = new File(path);
        // 创建新路径对象
        File fnewpath = new File(strNewPath);
        // 检查新路径是否存在，如果不存在则创建
        if (!fnewpath.exists()) {
            fnewpath.mkdirs();
        }
        // 创建新文件对象，用于检查新路径下是否已存在同名文件
        File fnew = new File(strNewPath + fold.getName());
        // 如果新路径下已存在同名文件，则删除
        if (fnew.exists()) {
            fnew.delete();
        }
        // 将原文件重命名为新路径下的文件，完成移动
        fold.renameTo(fnew);
    }

    /**
     * 删除指定路径的文件
     *
     * @param pathname 文件的路径
     * @return 如果文件存在并成功删除，则返回true；否则返回false
     */
    public static boolean deleteFile(String pathname) {
        boolean result = false;
        // 根据给定路径创建文件对象
        File file = new File(pathname);
        // 检查文件是否存在，如果存在则尝试删除
        if (file.exists()) {
            file.delete();
            result = true;
        }
        // 返回删除结果
        return result;
    }

    /**
     * 删除某个文件夹下的所有文件夹和文件
     * 此方法首先判断给定路径是否为目录，如果是，则递归删除其下的所有文件和子目录
     * 如果不是目录，则直接删除该文件
     *
     * @param delpath 待删除的文件或目录的路径
     * @return 总是返回true，如果删除过程中发生异常，则抛出异常
     * @throws Exception 如果删除文件或目录时发生错误，则抛出此异常
     */
    public static boolean deleteFiles(String delpath) {
        // 创建File对象以操作给定路径
        File file = new File(delpath);
        // 如果路径不是目录，则直接删除
        if (!file.isDirectory()) {
            // 删除文件夹
            file.delete();
        } else if (file.isDirectory()) {
            // 获取目录下的所有文件和子目录名
            String[] filelist = file.list();
            // 遍历文件和子目录列表
            for (int i = 0; i < filelist.length; i++) {
                // 文件删除
                File delfile = new File(delpath + "\\" + filelist[i]);
                // 如果当前项不是目录，则删除该文件
                if (!delfile.isDirectory()) {
                    delfile.delete();
                }
            }
            // 删除空目录
            file.delete();
        }
        // 返回true表示删除成功
        return true;
    }

    /**
     * 获取目录下所有文件(按时间排序)
     * 该方法递归地获取指定路径下的所有文件，并按照文件的最后修改时间进行排序
     * 如果目录下没有文件或路径无效，返回空列表
     *
     * @param path 字符串类型的路径，表示要获取文件的目录路径
     * @return 返回一个File类型的List列表，包含按最后修改时间降序排列的文件对象
     */
    public static List<File> getFileSort(String path) {
        // 递归获取指定路径下所有文件，存储在一个List列表中
        List<File> list = getFiles(path, new ArrayList<File>());
        // 检查列表是否非空且至少包含一个文件
        if (list != null && list.size() > 0) {
            // 对文件列表按照最后修改时间进行降序排序
            Collections.sort(list, new Comparator<File>() {
                // 比较两个文件的最后修改时间
                public int compare(File file, File newFile) {
                    // 如果当前文件的修改时间早于比较文件，则当前文件在排序后的列表中位置靠后
                    if (file.lastModified() < newFile.lastModified()) {
                        return 1;
                    } else if (file.lastModified() == newFile.lastModified()) {
                        // 如果两个文件修改时间相同，则保持原顺序
                        return 0;
                    } else {
                        // 如果当前文件的修改时间晚于比较文件，则当前文件在排序后的列表中位置靠前
                        return -1;
                    }
                }
            });
        }
        // 返回排序后的文件列表
        return list;
    }

    /**
     * 获取目录下所有文件
     *
     * @param realpath 目录的绝对路径
     * @param files    用于存储找到的文件的列表
     * @return 包含所有文件的列表
     */
    public static List<File> getFiles(String realpath, List<File> files) {
        // 根据给定的路径创建一个文件对象
        File realFile = new File(realpath);
        // 检查是否为目录
        if (realFile.isDirectory()) {
            // 获取目录下的所有子文件或子目录
            File[] subfiles = realFile.listFiles();
            // 遍历每个子文件或子目录
            for (File file : subfiles) {
                // 如果是目录，则递归调用getFiles方法
                if (file.isDirectory()) {
                    getFiles(file.getAbsolutePath(), files);
                } else {
                    // 如果不是目录，则将文件添加到列表中
                    files.add(file);
                }
            }
        }
        // 返回包含所有文件的列表
        return files;
    }
}


